<template>
  <el-table
  :data="tableData"
  style="width: 800px;"
  v-loading="loading"
  :element-loading-text="elementLoadingText"
  :element-loading-spinner="elementLoadingSpinner"
  :element-loading-svg-view-box="elementLoadingSvgViewBox"
  :element-loading-svg="elementLoadingSvg"
  :element-loading-background="elementLoadingBackground"
  @row-click="rowClick"
  :default-sort="defaultSort"
  :highlight-current-row = "highlightCurrentRow"
  @current-change="handleSelect"
  @selection-change="handleSelectionChange"
  v-bind="$attrs"
  >
    <el-table-column type="selection" width="55"></el-table-column>
    <template v-for="(item,index) in tableOption" :key="index">
      <el-table-column
          :label="item.label"
          :prop="item.prop"
          :align="item.align"
          :width="item.width"
      >
        <template #default="scope">
          <template v-if="scope.row.rowEdit">
            <el-input size="small" v-model="scope.row[item.prop!]"></el-input>
          </template>
          <template v-else>
            <template v-if="(scope.$index + scope.column.id) === currentEdit">
              <div class="edit-icon">
                <input v-model="scope.row[item.prop!]"/>
                <div @click.stop="clickEditCell">
                  <slot name="editCell" :scope="scope" v-if="$slots.editCell"> </slot>
                  <div class="icon" v-else>
                    <el-icon-check class="check" @click="confirm(scope)"></el-icon-check>
                    <el-icon-close class="close" @click="cancel(scope)"></el-icon-close>
                  </div>
                </div>
              </div>
            </template>
            <template v-else>
              <slot v-if="item.slot"  :name="item.slot" :scope="scope"></slot>
              <span v-else>{{ scope.row[item.prop!] }}</span>
              <component
                  :is="`el-icon-${toLine(editIcon)}`"
                  @click.stop="clickEdit(scope)"
                  v-if="item.editable"
                  class="edit"
              ></component>
            </template>
          </template>
        </template>
      </el-table-column>
    </template>
    <el-table-column
        :label="actionOptions!.label"
        :align="actionOptions!.align"
        :action="actionOptions!.align"
        :width="180"
    >
      <template #default="scope">
        <slot name="editRow" v-if="scope.row.rowEdit"></slot>
        <slot name="action" :scope="scope" v-else></slot>
      </template>
    </el-table-column>
  </el-table>
  <div class="pagination"
       v-if="pagination && !loading"
       :style="{ justifyContent }"
  >
    <el-pagination
        :current-page="currentPage"
        :page-size="pageSize"
        :page-sizes="pageSizes"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
import {TableOptions} from "./type.ts";
import {PropType, computed, ref, onMounted, watch} from "vue";
import {toLine} from "../../utils";
import {cloneDeep} from "lodash";

let props =defineProps({
  // 表格配置选项
  options: {
    type: Array as PropType<TableOptions[]>,
    required: true
  },
  // 表格数据
  data: {
    type: Array,
    required: true
  },
  // 加载文案
  elementLoadingText: {
    type: String,
  },
  // 加载图标名
  elementLoadingSpinner: {
    type: String,
  },
  // 加载背景颜色
  elementLoadingBackground: {
    type: String,
  },
  // 加载图标是svg
  elementLoadingSvg: {
    type: String
  },
  // 加载团是svg的配置
  elementLoadingSvgViewBox: {
    type: String,
  },
  // 编辑显示的图标
  editIcon: {
    type: String,
    default: 'Edit'
  },
  // 是否可以编辑行
  isEditRow: {
    type: Boolean,
    default: false
  },
  // 编辑行按钮的标识
  editRowIndex: {
    type: String,
    default: ''
  },
  // 是否显示分页
  pagination: {
    type: Boolean,
    default: false
  },
  // 显示分页的对齐方式
  paginationAlign: {
    type: String as PropType<'left' | 'center' | 'right'>,
    default: 'left'
  },
  // 当前是第几页
  currentPage: {
    type: Number,
    default: 1
  },
  // 当前一页多少条数据
  pageSize: {
    type: Number,
    default: 10
  },
  // 显示分页数据多少条的选项
  pageSizes: {
    type: Array as PropType<number[]>,
    default: () => [10, 20, 30, 40]
  },
  // 数据总条数
  total: {
    type: Number,
    default: 0
  },
  //排序
  defaultSort:{
    type:Object,
    default:{},
  },
  highlightCurrentRow:{
    type:Boolean,
    default:false,
  }
})

let tableOption = computed(() => props.options.filter(item => !item.action))

let actionOptions = computed(() => props.options.filter(item => item.action))

let loading = computed(()=> !props.data || !props.data.length)

let emits = defineEmits(['confirm','cancel',
  'update:editRowIndex','size-change',
  'current-change','handle-select','handle-selection'])

let clickEdit = (scope:any)=>{
    currentEdit.value = scope.$index + scope.column.id
}

let currentEdit = ref<string>('')

let tableData = ref<any[]>(cloneDeep(props.data))

let cloneEditRowIndex = ref<string>(props.editRowIndex)
onMounted(()=>{
  tableData.value.map((item)=>{
    item.rowEdit = false
  })
})

let handleSelect=(val:any)=>{
  emits('handle-select',val)
}
const multipleSelection = ref<any[]>([])
let handleSelectionChange=(val:any)=>{
  multipleSelection.value = val
  emits('handle-selection',val)
}

watch(()=>props.data,val=>{
  tableData.value = val;
  tableData.value.map((item)=>{
    item.rowEdit = false
  }),{deep: true}
})

// 监听
watch(() => props.editRowIndex, val => {
  if (val) cloneEditRowIndex.value = val
})


let confirm = (scope:any)=>{
  emits('confirm',scope)
}

let cancel = (scope:any)=>{
  emits('cancel',scope)
}

let clickEditCell = ()=>{
  currentEdit.value = ''
}

// 点击行的事件
let rowClick = (row: any, column: any) => {
  // 判断是否是点击的操作项
  if (column.label === actionOptions.value!.label){
    if(props.isEditRow && cloneEditRowIndex.value=== props.editRowIndex){
      row.rowEdit = !row.rowEdit
        tableData.value.map(item=>{
          if(item !== row){
            item.rowEdit = false
          }
        })
        if(!row.rowEdit) emits('update:editRowIndex', '')
    }
  }
}

// 分页的每一页数据变化
let handleSizeChange = (val: number) => {
  emits('size-change', val)
  // console.log(val)
}
// 分页页数改变
let handleCurrentChange = (val: number) => {
  emits('current-change', val)
  // console.log(val)
}

// 表格分页的排列方式
let justifyContent = computed(() => {
  if (props.paginationAlign === 'left') return 'flex-start'
  else if (props.paginationAlign === 'right') return 'flex-end'
  else return 'center'
})
</script>

<style lang="scss" scoped>
.edit{
  height: 1em;
  width: 1em;
  position: relative;
  top: 2px;
  left: 4px;
  cursor: pointer;
}
.edit-icon{
  display: flex;
  position: relative;
}
.icon{
  display: flex;
  position: absolute;
  top: 2px;
  right: 34px;
  svg{
    width: 1em;
    height: 1em;
    cursor: pointer;
  }
}
.check{
  color: red;
}
.close{
  color:green;
}
.pagination{
  margin-top: 16px;
  margin-right: 4px;
  display: flex;
}
</style>
